<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>编辑商品SKU</title>
  <link href="../../static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
  <link href="../../static/vendor/bootstrap-icons/bootstrap-icons.min.css" rel="stylesheet">
  <link href="../../static/css/vui365.min.css" rel="stylesheet">
  <style>
    #skuListContainer input[type="search"] {
      width: 100px !important;
    }

    #skuListContainer .col {
      border: 1px solid #efefef;
    }

    .btn-toggle {
      color: #999
    }

    td a img {
      width: 27px;
      height: 27px;
    }
  </style>
</head>

<body>
  <div id="app">
    <form class="form-main form-horizontal" style="height:100vh" method="POST" ref="editForm">
      <div class="form-body container-fluid p-3"
        style="height:calc(100% - 45px); overflow-y: auto; overflow-x: hidden;">
        <div class="sku">
          <div class="spec-container">
            <label class="form-label">商品规格<a class="ms-2 btn-toggle" href="#" title="展开或收起内容"
                @click.prevent="onTogglePanel">&equiv;</a></label>
            <div class="goods-spec-list">
              <div class="card mb-1" v-for="(item, idx) of dataOfSpec" :key="idx">
                <div class="card-header px-2 py-1">
                  {{item.spec_name}}<a class="ms-2 btn-toggle" href="#" title="展开或收起内容"
                    @click.prevent="onTogglePanel">&equiv;</a>
                </div>
                <div class="card-body d-flex flex-wrap px-2 py-1">
                  <div class="form-check form-check-inline" v-for="(item2, idx2) of item.children">
                    <input class="form-check-input" type="checkbox" :checked="item2._isChecked"
                      @click="onChangeSpec($event,item2)">
                    <label class="form-check-label">{{item2.spec_name}}</label>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="sku-container mt-3">
            <label class="form-label">SKU列表</label>
            <div class="mt-1">
              <div class="input-group input-group-sm mb-1">
                <span class="input-group-text">批量设置：</span>
                <input type="search" class="form-control form-control-sm" placeholder="图片" title="图片"
                  v-model="batchFillData.icon" />
                <input type="search" class="form-control form-control-sm" placeholder="价格" title="价格"
                  v-model="batchFillData.price" />
                <input type="search" class="form-control form-control-sm" placeholder="数量" title="数量"
                  v-model="batchFillData.quantity" />
                <button class="btn btn-sm btn-secondary" @click.prevent="onBatchFill()">
                  立即设置
                </button>
              </div>
              <div id="skuListContainer" style="width: 100%; overflow: auto">
                <table class="table table-sm table-bordered">
                  <thead>
                    <tr>
                      <th>#</th>
                      <th class="text-nowrap" v-for="(item, idx) of dataOfCheckedSpec" :key="idx">
                        {{ item.text }}
                      </th>
                      <th class="text-nowrap">价格</th>
                      <th class="text-nowrap">数量</th>
                      <th class="text-nowrap">图片</th>
                      <th class="text-nowrap">默认选中</th>
                    </tr>
                  </thead>
                  <tbody v-if="this.dataOfSku.length>0">
                    <tr v-for="(row, idx) of dataOfRows" :key="idx">
                      <td>{{ idx + 1 }}</td>
                      <td v-for="(item, idx2) of row" :key="idx2">
                        {{ item.text }}
                      </td>
                      <td>
                        <input class="form-control form-control-sm" type="number" placeholder="价格"
                          v-model="dataOfSku[idx]['price']" required min="0" />
                      </td>
                      <td>
                        <input class="form-control form-control-sm" type="number" placeholder="数量"
                          v-model="dataOfSku[idx]['quantity']" required min="0" />
                      </td>
                      <td>
                        <div class="d-flex align-items-center">
                          <a v-show="dataOfSku[idx]['icon'].length>0" :href="dataOfSku[idx]['icon']" target="_blank"
                            title="点击打开大图预览"><img :src="dataOfSku[idx]['icon']" alt="" loading="lazy"
                              class="border" /></a>
                          <input class="border" style="padding:.17rem 1rem;border-radius: .2rem;" type="search"
                            placeholder="图片地址" v-model="dataOfSku[idx]['icon']" required />
                          <button class="btn btn-sm btn-secondary" @click.prevent="onBrowserImage(idx)"
                            title="选择图片并上传">+</button>
                        </div>
                      </td>
                      <td>
                        <input type="radio" name="is_default" value="1" v-model="dataOfSku[idx]['is_default']" />
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </div>
        <!-- /.form-body -->
      </div>
      <div class="form-footer border-top pt-2 w-100 text-end">
        <button type="button" class="btn btn-secondary" @click.prevent="onCancelHandle()">取消</button>
        <cd-button class="btn btn-primary mx-2" @click="onSubmitHandle()">保存</cd-button>
      </div>
    </form>
    <input type="file" ref="file" style="display: none;" />
  </div>

  <script src="../../static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
  <script src="../../static/vendor/vue/vue.global.prod.min.js"></script>
  <script>
    // 全局配置
    this.vui365 = this.parent.vui365;

    // API接口配置
    const UrlCfg = {
      show: '/api/admin/ec-goods/{id}', // GET
      update: '/api/admin/ec-goods/update-sku/{id}', // POST
      upload: '/api/admin/uploader', // POST
    }
    /**
     * 管理员组件
     * @description 管理员组件
     */
    const App = {
      // data 配置
      data() {
        return {
          id: 0,
          dataOfMain: {
            data: {},
            status_data: []
          },
          // 商品类别的规格数据
          dataOfSpec: [],
          // 商品的SKU数据
          dataOfSku: [
            // { sku_no: "", price: 10.0, quantity: 10, icon: "", is_default: 0,},
          ],
          // 勾选的规格组合成的表格所有行
          dataOfRows: [],
          // 勾选的规格
          dataOfCheckedSpec: [],
          // 勾选的规格ID数组
          dataOfCheckedSpecIds: [],
          // 批量设置数据
          batchFillData: { price: "", quantity: "", icon: "", },
        };
      },
      // methods 配置
      methods: {
        // 初始化页面数据
        initData() {
          this.loadFormData();
        },
        // 初始化页面视图
        initView() {
          // 移除骨架屏
          document.querySelectorAll('.skeleton').forEach(el => {
            el.classList.remove("skeleton");
          })
          // 文件上传
          this.$refs.file.addEventListener('change', async (evt) => {
            let files = evt.target.files;
            if (files.length < 1) {
              alert("提示：您没有选择任何文件");
              return;
            }
            let formData = new FormData(),
              isMultiple = files.length > 1;
            formData.append("is_multiple", isMultiple ? 1 : 0);
            if (isMultiple) {
              for (let file of files) {
                if (typeof file == "object") {
                  formData.append("file[]", file);
                }
              }
            } else {
              formData.append("file", files[0]);
            }
            vui365.globalApp.showLoading();
            const msgInfo = await vui365.stdAxios(UrlCfg.upload, formData, 'POST');
            vui365.globalApp.hideLoading();
            if (msgInfo.status == 0) {
              alert(msgInfo.message);
              return;
            }
            if (Array.isArray(msgInfo.data)) {
              let paths = [];
              msgInfo.data.forEach((row) => {
                paths.push(row.path);
              });
              msgInfo.data = paths.join(',');
            }
            let idx = parseInt(evt.target.dataset.idx);
            this.dataOfSku[idx]['icon'] = msgInfo.data;
          })
        },
        // 加载表单数据
        async loadFormData() {
          vui365.globalApp.showLoading();
          const msgInfo = await vui365.stdAxios(UrlCfg.show.replace('{id}', this.id), { _mode: 'sku' }, 'GET');
          vui365.globalApp.hideLoading();
          console.log("[加载表单数据] msgInfo=", this.id, msgInfo);
          if (msgInfo.status == 0) {
            alert(msgInfo.message);
            return;
          }
          this.dataOfMain = msgInfo.data;
          this.dataOfSpec = msgInfo.data.specs_data;
          if (msgInfo.data.data.spec_data.length > 0) {
            this.dataOfCheckedSpecIds = JSON.parse(msgInfo.data.data.spec_data);
          }
          this.dataOfSpec.forEach(item => {
            item.children.forEach(item2 => {
              item2._isChecked = this.dataOfCheckedSpecIds.indexOf(item2.id) > -1;
            })
          })
          this.dataOfSku = msgInfo.data.skus_data;
          this.getDataOfCheckedSpec();
          // console.log("[加载表单数据] data=", this.dataOfMain);
        },
        // 处理表单提交事件
        async onSubmitHandle() {
          let elForm = document.querySelector("form");
          // 表单原生校验方法
          if (!elForm.checkValidity()) {
            elForm.reportValidity();
            return;
          }
          let data = {
            spec_data: this.dataOfCheckedSpecIds,
            sku_data: this.dataOfSku,
            _mode: 'sku',
          }
          let msgInfo = await vui365.stdAxios(UrlCfg.update.replace('{id}', this.id), data, 'POST');

          console.log("[提交表单] msgInfo=", msgInfo, data);
          if (msgInfo.status == 0) {
            if (typeof msgInfo.message == "object") {
              let messageArr = [];
              for (let k in msgInfo.message) {
                msgInfo.message[k].forEach((text) => {
                  messageArr.push(text);
                });
              }
              msgInfo.message = messageArr.join("<br />");
            }
            vui365.BsDialog.alert(msgInfo.message);
            console.log('显示错误');
            return;
          }

          console.log('刷新表格');
          vui365.globalApp.closeFormDialog();
          vui365.globalApp.refreshDataTable()
        },
        // 多维数组组合(不重复) 
        combination(data, isSkuNo = false) {
          let sarr = [[]];
          let result = [];
          for (let i = 0; i < data.length; i++) {
            let tarr = [];
            for (let j = 0; j < sarr.length; j++) {
              for (let k = 0; k < data[i].length; k++) {
                tarr.push(sarr[j].concat(data[i][k]));
              }
            }
            sarr = tarr;
          }
          for (let m = 0; m < sarr.length; m++) {
            if (isSkuNo) {
              let valArr=[];
              sarr[m].forEach(item=>{
                valArr.push(item.value)
              })
              result.push('x'+valArr.join('x')+'x');
            } else {
              result.push(sarr[m]);
            }
          }
          return result;
        },
        // 批量设置值
        onBatchFill() {
          this.dataOfSku.forEach((item) => {
            for (let k in this.batchFillData) {
              item[k] = this.batchFillData[k];
            }
          });
        },
        onChangeSpec($event, item) {
          item._isChecked = $event.target.checked;
          this.getDataOfCheckedSpec();
          // 重新生成 SKU 数据
          this.dataOfSku = [];
          let skuNo = [];
          this.dataOfRows.forEach((row) => {
            skuNo = [];
            row.forEach(item => {
              skuNo.push(item.value)
            })
            this.dataOfSku.push({
              sku_no: "x" + skuNo.join("x") + "x",
              price: 0,
              quantity: 0,
              is_default: 0,
              icon: "",
            });
          });
        },
        // 获取选中的规格组合列表
        getDataOfCheckedSpec() {
          let dataOfChecked = [], dataOfChecked2 = [];
          this.dataOfCheckedSpecIds = [];
          this.dataOfSpec.forEach(item => {
            dataOfChecked2 = [];
            item.children.forEach(item2 => {
              if (item2._isChecked) {
                this.dataOfCheckedSpecIds.push(item2.id);
                dataOfChecked2.push({ value: item2.id, text: item2.spec_name });
              }
            })
            if (dataOfChecked2.length > 0) {
              dataOfChecked.push({ value: item.id, text: item.spec_name, children: dataOfChecked2, },);
            }
          })
          // 所有数据行
          let data = [];
          dataOfChecked.forEach(item => {
            data.push(item.children);
          })
          this.dataOfCheckedSpec = dataOfChecked;
          this.dataOfRows = this.combination(data);
          console.log('rows=', this.dataOfRows);
          console.log('rows2=', this.combination(data,true));
          return dataOfChecked;
        },
        // 展开或收起
        onTogglePanel($event) {
          $event.target.parentNode.nextElementSibling.classList.toggle('d-none')
        },
        // 浏览图片
        onBrowserImage(idx) {
          this.$refs.file.dataset.idx = idx;
          this.$refs.file.click();
        }
      },
      // created 生命周期方法
      created() {
        this.id = vui365.EsUtils.getQueryString("id", 0, window.location.search);
        this.initData();
      },
      // mounted 生命周期方法
      mounted() {
        this.initView();
      },
    };

    // 创建应用实例
    const app = Vue.createApp(App);
    //  注册组件
    app.component("CdButton", vui365.getComponentOfCdButton())
    // 加载根元素
    app.mount('#app');
  </script>

</body>

</html>